package ProxyDemo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//import com.sun.istack.internal.Nullable;
//import com.sun.org.apache.regexp.internal.recompile;


/**
 * 
 * @author zybw-kf01
 *
 */
public class ProxyInterface {
	public static void main(String[] args) {

		ProxyI create = create(ProxyI.class);
		String phone = create.phone(12345);
		System.out.println(phone);
	}

	public static <T> T create(final Class<T> service) {
		if (!service.isInterface()) {
			throw new IllegalArgumentException("API declarations must be interfaces.");
		}
		// Prevent API interfaces from extending other interfaces. This not only avoids
		// a bug in
		// Android (http://b.android.com/58753) but it forces composition of API
		// declarations which is
		// the recommended pattern.
		if (service.getInterfaces().length > 0) {
			throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
		}
//		Object newProxyInstance = Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
		return  (T)Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
				new InvocationHandler() {

		  /*	* 在invoke方法编码指定返回的代理对象干的工作
          * proxy : 把代理对象自己传递进来
					* method：把代理对象当前调用的方法传递进来
           * args:把方法参数传递进来
           * */

					@Override
//					public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
					public Object invoke(Object proxy, Method method,  Object[] args) throws Throwable {
//						// If the method is a method from Object then defer to normal invocation.
						if (method.getDeclaringClass() == Object.class) {
							return method.invoke(this, args);
						}
						
						System.out.println("开始代理工作");
//						Object invoke = method.invoke(this, args);
						System.out.println("结束代理工作");
						if (method.getName().equals("phone")){
							return (int)args[0]+" 代理修改";
						}

						Object invoke = method.invoke(proxy, args);
						return invoke;

//						return return method.invoke(this, args);
					}
				});
//		return null;

	}

}
